package com.diorsunion.hedge.algo.test;

import com.diorsunion.hedge.algo.Oper11;
import com.diorsunion.hedge.algo.Operation;
import com.diorsunion.hedge.quota.MACDFilter;
import com.diorsunion.hedge.bo.stockdatainit.StockPriceInit;
import com.diorsunion.hedge.util.CalendarUtils;
import com.diorsunion.hedge.domain.AccountManager;
import com.diorsunion.hedge.dal.entity.stock.Stock;
import com.diorsunion.hedge.dal.entity.stock.StockPrice;
import com.diorsunion.hedge.dal.repository.stock.StockPriceRepository;
import com.diorsunion.hedge.dal.repository.stock.StockRepository;
import com.diorsunion.hedge.quota.StockPriceExFilter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.*;

/**
 * Created by wanglaoshi on 2016/4/16.
 */
public class WinTest2 extends WinTest {
    final static double init_money = 100000;
    static Date begin;
    static Date end;
    @Resource @Qualifier("RealStockPriceInit")
    StockPriceInit stockPriceInit;
    @Resource
    StockPriceRepository stockPriceRepository;
    @Resource
    StockRepository stockRepository;
    static List<Operation> opers = new ArrayList<>();

    static {
        try {
            begin = CalendarUtils.parseSimple("2015-01-01");
            end = CalendarUtils.parseSimple("2016-04-31");
        } catch (ParseException e) {
            e.printStackTrace();
            System.exit(0);
        }
//        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/springbeans-ds-test.xml",
//                "classpath:spring/springbeans-mybatis.xml",
//                "classpath:spring/springbeans-bo.xml");
//        stockPriceInit = ctx.getBean("RealStockPriceInit", StockPriceInit.class);
//        stockPriceRepository = ctx.getBean("stockPriceRepository", StockPriceRepository.class);
//        stockRepository = ctx.getBean("stockRepository", StockRepository.class);
//        for(int i=-1;i>=-10;i-=3){
//            for(int j=-1;j>=-1;j-=1){
//                for(int y=1;y<10;y+=3)
//                opers.add(new Oper11(ImmutableMap.of(Operation.PROFIT,y,Operation.LOSS,i,Operation.DLOSS,j)));
//            }
//        }
//        opers.add(new Oper11(ImmutableMap.of(Operation.PROFIT,9,Operation.LOSS,-9,Operation.DLOSS,-3)));
        opers.add(new Oper11(ImmutableMap.of()));
    }

//    static final List<Stock> stockList = Lists.newArrayList(
//            new Stock("TQQQ"),
//            new Stock("SQQQ"),
//            new Stock("UVXY"),
//            new Stock("SVXY"),
//            new Stock("DWTI"),
//            new Stock("UWTI"),
//            new Stock("DUST"),
//            new Stock("NUGT"),
//            new Stock("YANG"),
//            new Stock("YINN"));
    static final List<Stock> stockList = Lists.newArrayList(new Stock("SPY")); //SGOC  CHIM CPGI
    static final List<StockPriceExFilter> stockUtils = Lists.newArrayList(new MACDFilter(12,26));//MACD过滤

    @Test
    public void test() {
//        List<Stock> stockList = stockRepository.findAll(0,1000);
        //初始化股票价格
        for (Operation oper : opers) {
            System.out.println("----------------------------------------------------------------");
            List<IncomeLog> logs = Lists.newArrayList();
            for(Stock stock:stockList){
                List<Date> dates = stockPriceInit.init(begin, end, stock);
                if(dates==null||dates.isEmpty()){
                    continue;
                }
                List<StockPrice> stockPriceList = stock.getSortedStockPriceList();
                if(stockPriceList==null||stockPriceList.isEmpty()){
                    continue;
                }
                stockUtils.forEach( x-> x.filter(null,null,stockPriceList));
                List<AccountManager> account_per_days = Lists.newArrayList();//每天的账户情况
                AccountManager accountManager = new AccountManager(dates.get(0), init_money, stock);//8
                account_per_days.add(accountManager);
//                System.out.println("第" + (1) + "天,初始化,启动资金" + init_money);
                oper.oper(accountManager, account_per_days);
                dates.remove(0);
                double lastValue = dayoper(dates, accountManager, account_per_days, oper);
                int days = account_per_days.size();
                oper.printTradeLogOrderByDate();
                IncomeLog log = new IncomeLog(days,stock,lastValue,init_money,oper.params);
                logs.add(log);
            }
            logs.stream()
                    .sorted((a,b)-> (int)(a.lastMoney-b.lastMoney))
                    .forEach(a-> System.out.println(a));
            int a[] = new int[]{0,0,0};
            double b[] = new double[]{0,0,0};
            for(IncomeLog log:logs){
                if(log.income>0){
                    a[0]++;
                    b[0]+=log.income;
                }else if(log.income<0){
                    a[1]++;
                    b[1]+=log.income;
                }else{
                    a[2]++;
                }
            }
            System.out.println("赢"+a[0]+",亏"+a[1]+",平"+a[2]);
            System.out.println("赢"+String.format("%.2f",a[0]==0?0:b[0]/a[0])+",亏"+String.format("%.2f",a[1]==0?0:b[1]/a[1]));

        }
        System.out.println("*--------------------------------------------------------------*");
    }

    static class IncomeLog{
        public int days;
        public double income;
        public Stock stock;
        public double lastMoney;
        public double initMoney;
        public Map param;

        public IncomeLog(int days, Stock stock, double lastMoney, double initMoney,Map param) {
            this.days = days;
            this.stock = stock;
            this.lastMoney = lastMoney;
            this.initMoney = initMoney;
            this.income = (lastMoney - init_money) * 100 / init_money;
            this.param = param;
        }

        @Override
        public String toString() {
            return stock.code+"操作" + days + "天,最终收益:" + String.format("%.2f",income) + "%"+","+param;
        }
    }
}
